package com.mls.fivedistrict.server.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mls.fivedistrict.common.PageFilter;
import com.mls.fivedistrict.common.ServiceResponse;
import com.mls.fivedistrict.dao.TaskCategoryMapper;
import com.mls.fivedistrict.dao.TaskMapper;
import com.mls.fivedistrict.enums.*;
import com.mls.fivedistrict.exception.CustomerException;
import com.mls.fivedistrict.pojo.*;
import com.mls.fivedistrict.server.*;
import com.mls.fivedistrict.util.TimeConstants;
import com.mls.fivedistrict.util.TimeUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

import static java.math.BigDecimal.ROUND_DOWN;

/**
 * Created by  lixiang   on 2018/3/24.
 */
@Service("taskService")
public class TaskServiceImpl implements TaskService {
    @Resource(name = "taskMapper")
    TaskMapper taskMapper;
    @Resource(name = "taskCategoryMapper")
    TaskCategoryMapper taskCategoryMapper;
    @Resource(name = "userTaskService")
    UserTaskService userTaskService;
    @Resource(name = "calculateService")
    CalculateService calculateService;
    @Resource(name = "userService")
    UserService userService;
    @Resource(name = "propertyService")
    PropertyService propertyService;
    @Resource(name = "gUserService")
    GUserService gUserService;
    @Resource(name = "recordService")
    RecordService recordService;
    @Resource(name = "integralService")
    IntegralService integralService;

    @Override
    public ServiceResponse addTask(Task task) {
        Date now = new Date();
        task.setCreateDate(now);
        task.setUpdateDate(now);
        task.setIsDelete(false);
        int row = taskMapper.insertSelective(task);
        if (row > 0) {
            return ServiceResponse.createSuccessResponse();
        }
        return ServiceResponse.createErrorResponse();
    }

    @Override
    public ServiceResponse editTask(Task task, Long taskId) {
        task.setId(taskId);
        Date now = new Date();
        task.setCreateDate(now);
        task.setUpdateDate(now);
        int row = taskMapper.updateByPrimaryKeySelective(task);
        if (row > 0) {
            return ServiceResponse.createSuccessResponse();
        }
        return ServiceResponse.createErrorResponse();
    }


    @Override
    public ServiceResponse getTaskList(PageFilter pageFilter) {
        PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
        TaskExample taskExample = new TaskExample();
        TaskExample.Criteria criteria = taskExample.createCriteria();
        criteria.andIsDeleteEqualTo(false);
        taskExample.setOrderByClause("create_date desc");

        List<Task> taskList = taskMapper.selectByExample(taskExample);
        PageInfo<Task> pageInfo = new PageInfo<>(taskList);
        return ServiceResponse.createSuccessResponse(pageInfo);
    }

    @Override
    public ServiceResponse getTask(Long id) {
        Task task = taskMapper.selectByPrimaryKey(id);
        return ServiceResponse.createSuccessResponse(task);
    }

    @Override
    public ServiceResponse saftDeleteTask(Long taskId) {
        int row = taskMapper.softDeleteById(taskId);
        if (row > 0) {
            return ServiceResponse.createSuccessResponse();
        }
        return ServiceResponse.createErrorResponse();
    }

    @Override
    public ServiceResponse deleteTask(Long taskId) {
        Task task = taskMapper.selectByPrimaryKey(taskId);
        task.setIsDelete(true);
        task.setUpdateDate(new Date());
        return editTask(task, taskId);
    }

    @Override
    public ServiceResponse getUserTask(PageFilter pageFilter) {
        PageHelper.startPage(pageFilter.getPageNum(), pageFilter.getPageSize());
        List<Task> tasks = taskMapper.selectUserTask(pageFilter.getFilterMap());
        PageInfo pageInfo = new PageInfo(tasks, 5);
        return ServiceResponse.createSuccessResponse(pageInfo);
    }

    @Override
    public ServiceResponse getCategoryList() {
        TaskCategoryExample taskCategoryExample = new TaskCategoryExample();
        List<TaskCategory> taskCategoryList = taskCategoryMapper.selectByExample(taskCategoryExample);
        return ServiceResponse.createSuccessResponse(taskCategoryList);
    }

    @Transactional
    @Override
    public int completeTask(Long taskId, Long userId, String source) {
        if (userTaskService.getUserTask(taskId, userId) != null) {
            throw new CustomerException("任务已完成，请勿重复操作");
        }
        Task task = taskMapper.selectByPrimaryKey(taskId);
        Optional.ofNullable(task).orElseThrow(() -> new CustomerException("任务不存在"));
        //1.像用户任务的关系表中添加一条记录
        UserTask userTask = new UserTask();
        userTask.setTaskId(taskId);
        userTask.setUserId(userId);
        int i = userTaskService.addUserTask(userTask);
        if (i > 0) {
            //2.赠送算力（内测用户30天内加成10%）
            User userDetail = userService.getUserDetail(userId);
            long timeSpanByNow = TimeUtils.getTimeSpanByNow("2018-04-05 00:00:00", TimeConstants.SEC);
            int calculateValue = task.getValue().intValue();
            if (calculateValue > 0) {
                if (userDetail.getIsSubscribe() && timeSpanByNow < 30 * 24 * 60 * 60) {
                    calculateValue = (int) (calculateValue * (1 + 0.1));
                }
                Calculate calculate = new Calculate();
                calculate.setUserId(userId);
                calculate.setType(task.getCalculateType());
                calculate.setValue(calculateValue);
                calculate.setSource(source);
                calculate.setTaskId(taskId);
                calculateService.addCalculate(calculate);
            }
            //3.如果赠送积分
            Long integralId = task.getIntegralId();
            if (integralId != null) {
                //3-1 根据积分和用户ID获取资产
                Property propertyDetailByIntegral = propertyService.getPropertyDetailByIntegral(integralId, userId);
                //3-2 判断积分是否存在 增加总资产
                //3-2-1 增加记录
                Record record = new Record();
                if (propertyDetailByIntegral == null) {
                    //代表第一次获得这种资产
                    Property property = new Property();
                    property.setIntegralId(integralId);
                    property.setTotal(task.getIntrgralValue());
                    property.setUserId(userId);
                    propertyService.addProperty(property);
                    record.setPropertyId(property.getId());
                } else {
                    //代表资产存在继续累加
                    Property property = new Property();
                    property.setId(propertyDetailByIntegral.getId());
                    property.setTotal(propertyDetailByIntegral.getTotal().add(task.getIntrgralValue()).setScale(8, ROUND_DOWN));
                    propertyService.editProperty(property);
                    record.setPropertyId(property.getId());
                }

                record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
                record.setSource(source);
                record.setChangeReason(source);
                record.setIntergralId(task.getIntegralId());
                record.setUserId(userId);
                record.setValue(task.getIntrgralValue());
                recordService.insertRecord(record);
                //添加使用积分
                Integral integralDetail = integralService.getIntegralDetail(integralId);
                Integral integral = new Integral();
                integral.setId(integralDetail.getId());
                integral.setUserIntegral(integralDetail.getUserIntegral().add(task.getIntrgralValue()).setScale(8, ROUND_DOWN));
                integralService.editIntegral(integral);

            }
        }

        return i;
    }

    @Transactional
    @Override
    public int completeBindTask(Long taskId, Long userId, Map params) {
        Integer g_user_id = Integer.valueOf(params.get("G_USER_ID") + "");
        User userByGD = userService.getUserByGD(g_user_id);
        if (userByGD != null) {
            throw new CustomerException("已绑定，请勿重复绑定");
        }
        int i = this.completeTask(taskId, userId, CalculateSourceEnum.Bind.getValue());
        if (i <= 0) {
            throw new CustomerException("绑定失败");
        }
        //更新用户资料  国盾的用户ID
        User user = new User();
        user.setId(userId);
        user.setgUserId(g_user_id);
        userService.editUser(user);
        //添加国盾资料库
        GUser gUser = new GUser();
        gUser.setgCreateDate((Date) params.get("G_CREATE_DATETIME"));
        gUser.setgUserId(Long.valueOf(params.get("G_USER_ID") + ""));
        gUser.setgUserName(String.valueOf(params.get("G_USER_NAME") + ""));
        gUser.setgUserState(String.valueOf(params.get("G_USER_STATUS") + ""));
        gUser.setUserId(userId);
        gUserService.addGUser(gUser);
        return i;
    }

    @Override
    public CalculateAndProperty completeTaskForAuth(Long taskId, Long userId) {
        if (userTaskService.getUserTask(taskId, userId) != null) {
            throw new CustomerException("任务已完成，请勿重复操作");
        }
        CalculateAndProperty calculateAndProperty = new CalculateAndProperty();
        Task task = taskMapper.selectByPrimaryKey(taskId);
        Optional.ofNullable(task).orElseThrow(() -> new CustomerException("任务不存在"));
        //1.像用户任务的关系表中添加一条记录
        UserTask userTask = new UserTask();
        userTask.setTaskId(taskId);
        userTask.setUserId(userId);
        int i = userTaskService.addUserTask(userTask);
        if (i <= 0) {
            throw new CustomerException("任务关系创建失败");
        }
        //2.赠送算力（内测用户30天内加成10%）
        User userDetail = userService.getUserDetail(userId);
        long timeSpanByNow = TimeUtils.getTimeSpanByNow("2018-04-05 00:00:00", TimeConstants.SEC);
        int calculateValue = task.getValue().intValue();
        if (userDetail.getIsSubscribe() && timeSpanByNow < 30 * 24 * 60 * 60) {
            calculateValue = (int) (calculateValue * (1 + 0.1));
        }
        Calculate calculate = new Calculate();
        calculate.setUserId(userId);
        calculate.setType(task.getCalculateType());
        calculate.setValue(calculateValue);
        calculate.setSource(CalculateSourceEnum.Authentication.getValue());
        calculate.setTaskId(taskId);
        ServiceResponse serviceResponse = calculateService.addCalculate(calculate);
        if (!serviceResponse.getState().equals(ResponseCode.SUCCESS.getCode())) {
            throw new CustomerException("添加算力失败");
        }
        calculateAndProperty.setCalculateId(calculate.getId());
        //3.如果赠送积分
        Long integralId = task.getIntegralId();
        if (integralId != null) {
            //3-1 根据积分和用户ID获取资产
            Property propertyDetailByIntegral = propertyService.getPropertyDetailByIntegral(integralId, userId);
            //3-2 判断积分是否存在 增加总资产
            //3-2-1 增加记录
            Record record = new Record();
            if (propertyDetailByIntegral == null) {
                //代表第一次获得这种资产
                Property property = new Property();
                property.setIntegralId(integralId);
                property.setTotal(task.getIntrgralValue());
                property.setUserId(userId);
                propertyService.addProperty(property);
                calculateAndProperty.setPropertyId(property.getId());
                record.setPropertyId(property.getId());
            } else {
                //代表资产存在继续累加
                Property property = new Property();
                property.setId(propertyDetailByIntegral.getId());
                property.setTotal(propertyDetailByIntegral.getTotal().add(task.getIntrgralValue()).setScale(8, ROUND_DOWN));
                propertyService.editProperty(property);
                calculateAndProperty.setPropertyId(propertyDetailByIntegral.getId());
                record.setPropertyId(property.getId());
            }

            record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
            record.setSource("完成实名认证");
            record.setIntergralId(task.getIntegralId());
            record.setUserId(userId);
            record.setValue(task.getIntrgralValue());
            recordService.insertRecord(record);
            //添加使用积分
            Integral integralDetail = integralService.getIntegralDetail(integralId);
            Integral integral = new Integral();
            integral.setId(integralDetail.getId());
            integral.setUserIntegral(integralDetail.getUserIntegral().add(task.getIntrgralValue()).setScale(8, ROUND_DOWN));
            integralService.editIntegral(integral);

        }
        return calculateAndProperty;
    }

    @Override
    public CalculateAndProperty completeTaskForInviterAuth(Long taskId, Long userId) {
        CalculateAndProperty calculateAndProperty = new CalculateAndProperty();
        Task task = taskMapper.selectByPrimaryKey(taskId);
        Optional.ofNullable(task).orElseThrow(() -> new CustomerException("任务不存在"));
        //2.赠送算力（内测用户30天内加成10%）
        User userDetail = userService.getUserDetail(userId);
        long timeSpanByNow = TimeUtils.getTimeSpanByNow("2018-04-05 00:00:00", TimeConstants.SEC);
        int calculateValue = task.getValue().intValue();
        if (userDetail.getIsSubscribe() && timeSpanByNow < 30 * 24 * 60 * 60) {
            calculateValue = (int) (calculateValue * (1 + 0.1));
        }
        Calculate calculate = new Calculate();
        calculate.setUserId(userId);
        calculate.setType(task.getCalculateType());
        calculate.setValue(calculateValue);
        calculate.setSource(CalculateSourceEnum.Invite.getValue());
        calculate.setTaskId(taskId);
        calculateService.addCalculate(calculate);
        calculateAndProperty.setCalculateId(calculate.getId());
        //3.如果赠送积分
        Long integralId = task.getIntegralId();
        if (integralId != null) {
            //3-1 根据积分和用户ID获取资产
            Property propertyDetailByIntegral = propertyService.getPropertyDetailByIntegral(integralId, userId);
            //3-2   判断积分是否存在 增加总资产
            //3-2-1 增加记录
            Record record = new Record();
            record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
            record.setSource(RecordProductTypeEnum.INVITE_FRIENDS.getValue());
            record.setIntergralId(task.getIntegralId());
            record.setUserId(userId);
            record.setValue(task.getIntrgralValue());
            if (propertyDetailByIntegral == null) {
                //代表第一次获得这种资产
                Property property = new Property();
                property.setIntegralId(integralId);
                property.setTotal(task.getIntrgralValue());
                property.setUserId(userId);
                propertyService.addProperty(property);
                calculateAndProperty.setPropertyId(property.getId());
                record.setPropertyId(property.getId());
            } else {
                //代表资产存在继续累加
                Property property = new Property();
                property.setId(propertyDetailByIntegral.getId());
                property.setTotal(propertyDetailByIntegral.getTotal().add(task.getIntrgralValue()).setScale(8, ROUND_DOWN));
                propertyService.editProperty(property);
                calculateAndProperty.setPropertyId(propertyDetailByIntegral.getId());
                record.setPropertyId(propertyDetailByIntegral.getId());
            }
            int i = recordService.insertRecord(record);
            if (i <= 0) {
                throw new CustomerException("记录创建失败");
            }
            //添加使用积分
            Integral integralDetail = integralService.getIntegralDetail(integralId);
            Integral integral = new Integral();
            integral.setId(integralDetail.getId());
            integral.setUserIntegral(integralDetail.getUserIntegral().add(task.getIntrgralValue()).setScale(8, ROUND_DOWN));
            integralService.editIntegral(integral);
        }
        return calculateAndProperty;

    }

    @Override
    public Task getTaskByCategory(String category) {
        TaskExample taskExample = new TaskExample();
        TaskExample.Criteria criteria = taskExample.createCriteria();
        criteria.andCategoryEqualTo(category);
        List<Task> tasks = taskMapper.selectByExample(taskExample);
        if (tasks.size() > 0) {
            return tasks.get(0);
        }
        return null;
    }

    @Override
    public UserTask getUserIsFace(Long userId) {
        Task faceTask = getTaskByCategory(TaskCategoryEnum.FACE_RECOGNITION.getValue());
        if (faceTask == null) {
            return null;
        }
        return userTaskService.getUserTask(faceTask.getId(), userId);
    }

    @Override
    public ServiceResponse getAllTask() {
        TaskExample taskExample = new TaskExample();
        List<Task> taskList = taskMapper.selectByExample(taskExample);
        return ServiceResponse.createSuccessResponse(taskList);
    }

    @Override
    public Task gettaskDetail(Long taskId) {
        Task task = taskMapper.selectByPrimaryKey(taskId);
        return task;
    }


}
